home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 October: Mac OS SDK / Dev.CD Oct 96 SDK / Dev.CD Oct 96 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / Documentation / Development Notes / Converting from d11 / Conversion from d11 (1) next >
Encoding:
Text File  |  1996-08-16  |  25.0 KB  |  519 lines  |  [TEXT/ttxt]

  1. OpenDoc
  2. Development
  3. Framework
  4. __________________________________________________________________________________________
  5. Converting from d11 - part I 
  6. ODF Release 1                                                                                                                                                                          
  7.  
  8.  
  9.  
  10. Table of Contents
  11.  
  12. • Files and Projects
  13.      • Project Folders
  14.      • Source Files
  15.      • Code Warrior Projects
  16. • Part API
  17. • Part (Content Model)
  18. • Selection (Content Model)
  19. • Commands
  20.      • Edit Commands
  21. • Drag and Drop
  22. • Embedding
  23.      • Insert command
  24. • Graphics
  25. • Linking
  26. • Menus
  27. • Notification
  28. • Promises
  29. • Resources
  30.      • About Box resource
  31.      • Menu resources
  32.      • Part Info resource
  33.      • View resources
  34. • Views
  35.  
  36.  
  37. Files and Projects
  38.  
  39. Project Folders
  40. The layout for project and source files has changed since d11. Sample parts now keep all their source files in one folder, called “Sources”, instead of dividing them into Sources, Include, and Other. The sample part folders are now inside the ODFDev folder, at the same level as the ODF folder. Each sample part folder contains a set of build folders for different build configurations - CWPPCDebug for Code Warrior PowerPC debug build, SC68KRelease for Symantec 68K non-debug build, etc. After building, the resulting part and sym files are located in the corresponding build folder. (Make an alias to the part file and place the alias in the Editors folder on the same disk, so that OpenDoc can find it.)
  41.  
  42. Source Files
  43. ODF uses these conventions for part source files:
  44. • Resource files (.fr suffix means a cross-platform resource file):
  45.      Menus.fr - menu and string resources
  46.      PartInfo.fr - PartInfo and About resources
  47.      Views.fr - view resources
  48.      Part.r - Mac-specific resources like 'cfrg' and nmaps
  49. • Files containing #defines that are used in both C++ and resource files have the suffix “.k”.
  50.      Binding.k contains definitions used in Part.r and Part.cpp - part kind string, editor string, etc.
  51.      Defines.k contains definitions used in .fr files - resource IDs, command IDs, etc.
  52.  
  53. In order to follow these conventions, you should discard your MyPartDef.h file and move its definitions into Binding.k and Defines.k files. You may also want to convert your menu and view creation code to resources. See the section “Resources” below.
  54.  
  55. Code Warrior Projects
  56. Code Warrior project files in ODF 1 are in CW8 format. To update your old CW7 project file, open it with CW8 and perform the following adjustments (debug version assumed):
  57. • Add the shared library, ODFLibrary (located in the Bin folder of SLPPCDebug)
  58. • Remove ODF .rsrc files such as FWOSMisc.rsrc (resources are now in the shared library)
  59. • Remove your part’s .rsrc files and add .r and .fr files (they can now be built using plug-ins)
  60. • In Preferences, change the access paths to look like this:
  61.    {Project ƒ}:
  62.    {Project ƒ}::Sources:
  63.    {Project ƒ}:::ODF:Found:
  64.    {Project ƒ}:::ODF:OS:
  65.    {Project ƒ}:::ODF:Framewrk:
  66.    {Project ƒ}:::ODF:CWPPCDebug:
  67.    {Project ƒ}:::ODF:SLPPCDebug:
  68.    ---
  69.    {Project ƒ}:::ODF:Found:ODUtils:Include:
  70.    {Compiler ƒ}:MacOS Support:Headers:
  71.    {Compiler ƒ}:MacOS Support:Libraries:
  72.    {Compiler ƒ}:MacOS Support:MacHeaders:
  73.  
  74.  
  75. Part API
  76.  
  77. The FW_CPart constructor API has changed. Formerly each part had static members for the part kind and user name strings. These strings have been moved into resources, so you can remove the data members kPartKind and kPartUserName from your part class definition. Also remove the static initialization statements from your Part.cpp file. Instead of taking the part kind, part user name, and icon id, the FW_CPart constructor now takes the id of a PartInfo resource.
  78.  
  79. Old part constructor:
  80. CHelloPart::CHelloPart(ODPart* odPart) :
  81.    FW_CPart(odPart, CHelloPart::kPartKind, CHelloPart::kPartUserName, FW_gInstance, kPartIconID),
  82.  
  83. New part constructor:
  84. CHelloPart::CHelloPart(ODPart* odPart) :
  85.    FW_CPart(odPart, FW_gInstance, kPartInfoID),
  86.  
  87. Normally you supply the PartInfo resource in the PartInfo.fr file:
  88. resource FW_RPartInfo(kPartInfoID)
  89. {
  90.    // ----- Icon ID
  91.    kMyIconID,
  92.     
  93.    // ----- Part Name
  94.    kMyEditorUserString,
  95.     
  96.    // ----- PartKind
  97.    kMyPartKind
  98. };
  99.  
  100. See the Engineering note “Part Info Resource” for more details on this resource.
  101.  
  102.  
  103. Part (Content Model)
  104.  
  105. There have been major changes to the way a part handles its data. ODF now has what we call the Content Model, in which persistent data is managed by Content objects (derived from FW_CContent). Part data is defined in a CPartContent class instead of in the part class. The part keeps a pointer to its part content object so that operations like internalizing and externalizing can be delegated to it.
  106.  
  107. Here is an outline of the steps to convert your part and its data to the new content model:
  108. - Make new files Content.h/.cpp.
  109. - Define CMyPartContent, which is a subclass of FW_CContent or FW_CEmbeddingContent. 
  110. - Remove all persistent data from the part class and move it into CMyPartContent.
  111. - Override FW_CPart::NewPartContent to create and return an instance of CMyPartContent.
  112. - Override these FW_CContent methods:
  113.      Externalize - move code from ExternalizeContent (you can remove the code to Focus/Remove/AddValue to the storage unit; ODF takes care of this for you in FW_CPart::ClearPartStorage)
  114.      Internalize - move code from InternalizeContent
  115. - (Embedding parts) Override these FW_CEmbeddingContent methods:
  116.      IsDataOnlyOneProxy - move code from IsSelectionOnlyOneProxy
  117. - Remove these methods from CMyPart:
  118.      ExternalizeContent
  119.      InternalizeContent
  120.  
  121. class CMyPart : public FW_CEmbeddingPart
  122. {
  123.   public:
  124.     FW_DECLARE_CLASS
  125.     FW_DECLARE_AUTO(CMyPart)
  126.  
  127.     CMyPart(ODPart* odPart);
  128.     virtual ~ CMyPart();
  129.  
  130.     virtual FW_CContent* NewPartContent(Environment* ev);
  131.     ...
  132.  
  133.   private:
  134.     CMyPartContent* fPartContent;
  135. };
  136.  
  137. FW_CContent* CMyPart::NewPartContent(Environment* ev)
  138. {
  139.     fPartContent = FW_NEW(CMyPartContent, (ev, this));
  140.     return fPartContent;
  141. }
  142.  
  143. class CMyPartContent : public FW_CEmbeddingContent
  144. {
  145.   public:
  146.     FW_DECLARE_AUTO(CMyPartContent)
  147.  
  148.     CMyPartContent(Environment* ev, CMyPart* part);
  149.     virtual ~CMyPartContent();
  150.  
  151.     virtual void Externalize(Environment* ev,
  152.                              ODStorageUnit* storageUnit,
  153.                              FW_EStorageKinds storageKind,
  154.                              FW_CCloneInfo* cloneInfo);
  155.  
  156.     virtual FW_Boolean Internalize(Environment* ev,
  157.                              ODStorageUnit* storageUnit, 
  158.                              FW_EStorageKinds storageKind,
  159.                              FW_CCloneInfo* cloneInfo);
  160.  
  161.     virtual FW_MProxy* IsDataOnlyOneProxy(Environment* ev) const;
  162.     ...
  163.  
  164.   private:
  165.     CMyPart* fMyPart;
  166.     // define data members for part content here
  167. };
  168.  
  169. See the Engineering Note “Content Model” for more recipes and diagrams.
  170. Also see the section “Defining your Part’s Content Object” on p.45 of the ODF Developer’s Guide.
  171.  
  172.  
  173. Selection (Content Model)
  174.  
  175. There have been massive changes to the way the selection handles its data, internalizes, and externalizes. Like part data, selection data is now kept in a content object to which in/externalize operations are delegated. The class FW_CEmbeddingSelection no longer exists, its role has been taken over by FW_CEmbeddingContent and other classes.
  176.  
  177. Here is an outline of the steps to convert your selection and its data to the content model:
  178. - Define CMySelectionContent, which is a subclass of FW_CContent or FW_CEmbeddingContent 
  179. - Remove all persistent data from the selection class and move it into CMySelectionContent
  180. - Override FW_CSelection::GetSelectedContent to return a pointer to the CMySelectionContent object
  181. - Override these FW_CContent methods:
  182.      Externalize - move code from DoExternalizeSelection
  183.      Internalize - move code from DoInternalizeSelection
  184.      CreateDataFrameShape - move code from CreateSelectionFrameShape
  185. - (Embedding parts) Override these FW_CEmbeddingContent methods:
  186.      IsDataOnlyOneProxy - adapt code from IsSelectionOnlyOneProxy
  187.      SingleEmbeddedFrameInternalized - adapt code from CMyFrame::EmbedSingleFrame
  188. - (Embedding parts) CMySelection should be derived from FW_CSelection, since FW_CEmbeddingSelection is gone
  189. - Remove these methods from CMySelection:
  190.      DoExternalizeSelection
  191.      DoInternalizeSelection
  192.      IsSelectionOnlyOneProxy
  193.      CreateSelectionFrameShape
  194.      InsertNewPart - this is now handled by the Insert command (see below)
  195. - Remove this method from CMyEmbeddingFrame:
  196.      EmbedSingleFrame
  197.  
  198. class CMySelection : public FW_CSelection
  199. {
  200.   public:
  201.     FW_DECLARE_AUTO(CMySelection)
  202.  
  203.     CMySelection(Environment* ev, CMyPart* part);
  204.     virtual ~ CMySelection();
  205.  
  206.     virtual FW_CContent* GetSelectedContent(Environment* ev);
  207.     ...
  208.  
  209.   private:
  210.     CMyPart* fMyPart;
  211.     CMySelectionContent* fSelectedContent;
  212. };
  213.  
  214. CMySelection::CMySelection(Environment* ev, CMyPart* part):
  215.     FW_CSelection(ev, false, false),
  216.     fMyPart(part),
  217.     fSelectedContent(NULL)
  218. {
  219.     fSelectedContent = FW_NEW(CMySelectionContent, (ev, part, this));
  220.     FW_END_CONSTRUCTOR
  221. }
  222.  
  223. FW_CContent* CMySelection::GetSelectedContent(Environment* ev)
  224. {
  225.     return fSelectedContent;
  226. }
  227.  
  228. class CMySelectionContent : public FW_CEmbeddingContent
  229. {
  230.   public:
  231.     FW_DECLARE_AUTO(CMySelectionContent)
  232.  
  233.     CMySelectionContent(Environment* ev, CMyPart* part, CMySelection* selection);
  234.     virtual ~CMySelectionContent();
  235.  
  236.     virtual ODShape* CreateDataFrameShape(Environment* ev) const;
  237.  
  238.     virtual void Externalize(Environment* ev,
  239.                              ODStorageUnit* storageUnit,
  240.                              FW_EStorageKinds storageKind,
  241.                              FW_CCloneInfo* cloneInfo);
  242.  
  243.     virtual FW_Boolean Internalize(Environment* ev,
  244.                              ODStorageUnit* storageUnit, 
  245.                              FW_EStorageKinds storageKind,
  246.                              FW_CCloneInfo* cloneInfo);
  247.  
  248.     virtual FW_MProxy* IsDataOnlyOneProxy(Environment* ev) const;
  249.  
  250.     virtual void SingleEmbeddedFrameInternalized(Environment* ev, 
  251.                              FW_CEmbeddingFrame* scopeFrame,
  252.                              ODPart* embeddedPart, 
  253.                              ODFrame* embeddedFrame,
  254.                              ODShape* suggestedShape,
  255.                              ODTypeToken viewType);
  256.     ...
  257.  
  258.   private:
  259.     CMyPart* fMyPart;
  260.     CMySelection* fMySelection;
  261.     // define data members for selected content here
  262. };
  263.  
  264. See the Engineering Note “Content Model” for more recipes and diagrams.
  265.  
  266.  
  267. Commands
  268.  
  269. The clipboard and drag and drop commands still use the selection object for internalizing and externalizing. However, the content object has taken over the role of managing the data.
  270.  
  271. • Call cmd->Execute(ev) instead of part->ExecuteCommand(ev, cmd);
  272.  
  273. • All the fields of FW_CCommand are now private, so you’ll have to use inline accessors:
  274.    fCommandID    GetCommandID(ev)
  275.    fFrame        GetFrame(ev)
  276.    fPart        GetPart(ev)
  277.  
  278. • The field fSelection has been removed from FW_CCommand, and added to the commands that use it: FW_CClipboardCommand, FW_CDragCommand, and FW_CDropCommand.
  279.  
  280. Edit Commands
  281. FW_CEditCommand has been renamed to FW_CClipboardCommand. It still handles the same menu commands: Cut, Copy, Paste, Paste As, Clear, Select All.
  282.  
  283. • The following methods were removed: 
  284.    DoClear
  285.    DoCut
  286.    DoPaste
  287.    DoPasteAs
  288. If you overrode any of these methods in d11, move the code into CommandDone. CommandDone is called after the operation has been successfully completed. There is a new method PreCommand, which is called before the operation is done. You might want to override PreCommand to close your selection before a Paste, for example.
  289.  
  290. • You no longer need to call SetMenuStrings. ODF sets the undo strings to default values for clipboard commands.
  291.  
  292.  
  293. Drag and Drop
  294.  
  295. In the d11 version of ODF, drag and drop support was automatically available to all frames because FW_MDragDroppable was mixed into FW_CFrame. In ODF 1 the class FW_MDragDroppable has been split into two mixin classes, FW_MDraggableFrame and FW_MDroppableFrame. If you want your frame to support dragging and/or dropping, you must specify it yourself as described below. It’s a little bit more flexible in that your frame can support dropping without dragging, and vice-versa.
  296.  
  297. • If your frame has draggable content, do the following:
  298.     mixin FW_MDraggableFrame
  299.     override FW_CSelection::IsMouseInDraggableItem if desired (unchanged from d11)
  300. • If your frame supports dropping, do the following:
  301.     mixin FW_MDroppableFrame
  302.     override FW_CFrame::CanAcceptDrop
  303.     remove call to SetDroppable, since the FW_MDroppableFrame constructor calls it
  304.  
  305. Undo strings are set automatically to defaults, so you can remove SetMenuStrings calls from your command constructors.
  306.  
  307.  
  308. Embedding
  309.  
  310. The following virtual methods were removed from ODF:
  311.    FW_CEmbeddingFrame::EmbedSingleFrame
  312.       override FW_CEmbeddingContent::SingleEmbeddedFrameInternalized
  313.    FW_CEmbeddingSelection::IsSelectionOnlyOneProxy
  314.       override FW_CEmbeddingContent::IsDataOnlyOneProxy
  315.    FW_CEmbeddingSelection::InsertNewPart
  316.       Functionality moved to FW_CInsertCommand (see next section)
  317.  
  318. See the documents in the Embedding folder of the Engineering Notes.
  319.  
  320. Insert Command
  321. The Insert menu command is now handled by the ODF class FW_CInsertCommand. The inserted part will be added to your selection’s content object. If you want this command to be undoable (strongly recommended), you must subclass it and provide appropriate UndoIt and RedoIt methods. FW_CEmbeddingFrame defines a factory method which you must override to create your subclass of FW_CInsertCommand. For example, from the Draw sample:
  322.  
  323. FW_CInsertCommand* CDrawFrame::NewInsertCommand(Environment* ev,
  324.                                                 const FW_PFileSpecification& fileSpec)
  325. {
  326.     return FW_NEW(CDrawInsertCommand, (ev, this, fileSpec, fSelection, FW_kCanUndo));
  327. }
  328.  
  329.  
  330. Graphics
  331.  
  332. Changes to Graphics for moving the code to the shared library:
  333.  
  334. • The classes listed below have been moved to the SL using a "handle/wrapper" technique: There is an opaque "handle" data type and a set of APIs exported from the SL that create/destroy/manipulate the handle.  Then there is a C++ wrapper class that owns a handle of that type, and contains inline methods that simply delegate to the appropriate exported SL APIs.
  335.  
  336.      FW_PInk                 FW_PStyle                 FW_PPattern        
  337.      FW_PFont               FW_PBitmap               FW_PPicture
  338.      FW_PIcon               FW_PPolygon
  339.  
  340. In each case, the handle type wrapped by a C++ class FW_Pxxx is FW_Hxxx, so FW_PIcon wraps FW_HIcon, FW_PFont wraps FW_HFont, etc.
  341.  
  342. These classes used to be smart pointer classes that overloaded operator->() to implement delegation to the "Rep" object.  Thus their methods were called like: "font-> SetFontName(name)".  With the new approach, the delegation is done using inlines (as described above), so the normal method-calling syntax should be used, as in "font.SetFontName(name)".
  343.  
  344. • FW_CGraphicDevice is only exported as an opaque handle type, FW_HGDevice.
  345.  
  346. • FW_CMapping and FW_CGraphicContext have been split into a private structure (FW_SMapping and FW_SGraphicsContext, respectively) and a C++ subclass with wrapper functions.  The structures should not be used directly, use the C++ wrappers instead.
  347.  
  348. • Removed FW_CRasterizer class.  This should not affect your code unless you call its methods directly.  You can use functions in SLRender.h to render without creating shapes, but the preferred way to do this is to use static methods of various shape classes, as in "FW_CRectShape::RenderRect(gc, rect, FW_kFrame);"
  349.  
  350. • Changed global color constants from "const FW_CColor" to "const FW_SColor"
  351.     
  352. • Fixed point math: instead of a class, FW_CFixed, with operators defined as members, there is now a struct, FW_Fixed, with operators defined in the global scope.  This was done because we can't pass C++ objects across SOM boundaries, only plain C data types and simple structs made from them.
  353.     
  354. This means that you can't use member functions of FW_CFixed anymore.  For example, you will need to change:
  355.     
  356.                  fx.Half()                            FW_Half(fx)
  357.                  fx.DividedByInt(n)     FW_DividedByInt(fx, n)
  358.                  fx.RoundedToInt()      FW_RoundedToInt(fx)
  359.                  fx.Sin()                              FW_Sin(fx)
  360.         
  361. The same goes for the FW_CWide class: it's been "struct"-ified into FW_Wide.
  362.  
  363. See the chapter on Graphics in the ODF Developer’s Guide.
  364.  
  365.  
  366. Linking
  367.  
  368. Linking has undergone a massive renaming. See the text file ODF API Changes for a long list of class and method names that have changed. Basically, the term “Publish” was replaced with “LinkSource” and the term “Subscribe” was replaced with “LinkDestination”. The methods called “Publish” and “Subscribe” have been renamed to “LinkEstablished” to more accurately reflect their purpose.
  369.  
  370. Linking has also undergone some restructuring. There is a new base class for both link sources and destinations. This class (FW_CLink) provides the API for link borders and selection, although support for these features is still incomplete in ODF.
  371.  
  372. There is more support for in/externalizing persistent links in ODF1, mostly in the class FW_CLinkManager. The method GetPublishFormat has been moved to FW_CLinkManager and renamed to GetSourceLinkFormat. It has a companion method GetDestLinkFormat which must also be overridden, since the value strings for source and destination links must be different. FW_CLinkManager now has six methods that must be overridden. Besides the format string functions there are the original two, NewLinkSource and NewLinkDestination (formerly called NewPublishLink and NewSubscribeLink). And finally, there are two methods for internalizing links from a storage unit, DoInternalizeOneSourceLink and DoInternalizeOneDestLink.
  373.  
  374. See the sample parts Draw and Table for examples of linking.
  375.  
  376.  
  377. Menus
  378.  
  379. In FW_CPulldownMenu, all methods for adding menu items using string resources have been removed: 
  380.    AppendTextItem
  381.    AppendToggleItem
  382.    InsertTextItem, InsertTextItemAfterCommand
  383.    InsertToggleItem, InsertToggleItemAfterCommand
  384.  
  385. You can now define your menus in resources. For example, in the d11 version of the Hello sample each menu and menu item had to be created individually: 
  386. FW_CPullDownMenu* pullDownMenu = new FW_CPullDownMenu(ev, resFile, kHelloPartStrings, kHelloMenuString);
  387. pullDownMenu->AppendTextItem(ev, resFile, kHelloPartStrings, kFirstMenuString, cFirstCommand, '1');
  388. pullDownMenu->AppendTextItem(ev, resFile, kHelloPartStrings, kSecondMenuString, cSecondCommand, '2');
  389. GetMenuBar(ev)->AdoptMenuLast(ev, pullDownMenu);
  390.  
  391. In ODF 1 this process is simplified to one line:
  392.    GetMenuBar(ev)->InitializeFromResource(ev, kMenuBar);
  393.  
  394. See the Engineering Note “Menu Resources” for information on defining menus in resources.
  395.  
  396. The following methods have been removed from FW_CMenuItem and its subclasses:
  397.    FW_CMenuItem: GetMenuKey, GetItemText
  398.    FW_CTextItem: GetMenuKey, GetItemText, SetItemText
  399.    FW_CToggleItem: GetTrueString, GetFalseString
  400.  
  401. Use the FW_CMenuBar API to get information about a menu item. For example:
  402.    FW_CString itemString;
  403.    menuBar->GetItemString(ev, commandID, itemString);
  404.    FW_MenuKey menuKey = menuBar->GetMenuKey(ev, commandID);
  405.  
  406.  
  407. Notification
  408.  
  409. Notification has been simplified. The class FW_CConnection has been removed and its functionality has been rolled into FW_MReceiver. There are now only four classes involved in notification: FW_MReceiver, FW_MNotifier, FW_CInterest, and FW_CNotification.
  410.  
  411. FW_CInterest API changes:
  412.     Instead of FW_TypeToken fName, uses FW_Message fMessage to describe the type of notification. 
  413.     Constructor parameter change (FW_TypeToken name replaced by FW_Message msg). 
  414.     GetName (returned an FW_TypeToken) replaced by GetMessage (returns an FW_Message)
  415. FW_CNotification API changes:
  416.     GetName (returned an FW_TypeToken) replaced by GetMessage (returns an FW_Message)
  417.     new method SetInterest
  418. FW_MNotifier API changes:
  419.     Notify method takes an ev parameter
  420.     AddConnection renamed to AddReceiver; 1st param is an FW_MReceiver instead of an FW_CConnection
  421.     RemoveConnection renamed to RemoveReceiver; 1st param change as above
  422.     new method IsConnectedTo
  423. FW_MReceiver API changes:
  424.     HandleNotification method takes an ev parameter
  425.     added methods from defunct FW_CConnection: RemoveAllInterests, RemoveInterest, Connect, Disconnect, IsConnected
  426.     new methods AddInterest, AddNotifier, RemoveNotifier
  427. Other API changes:
  428.     FW_CFrame::AddConnection is gone; use FW_MReceiver::AddInterest instead.
  429.  
  430. All notifiers now send a FW_kNotifierDeletedMsg message in their destructor to let their receivers know that they are going away.  This is used for example by FW_CRadioCluster objects which delete themselves after the last radio button has been deleted.
  431.  
  432. See the Engineering Note “Notification” for details and sample code.
  433.  
  434.  
  435. Promises
  436.  
  437. Promises are no longer handled by FW_CPart. Members related to promises have been moved to the class FW_CDataInterchange.
  438.  
  439. FW_CSelection::NewPromise is gone. Override FW_CContent::Externalize and create the promise(s) there. Then call aPromise->Promise(ev, storageUnit, property, value) for each promise.
  440.  
  441. FW_CPart::GetPromise is also gone. ODF’s data interchange object keeps track of promises created for clipboard commands, drag and drop, and linking. If you need to access a promise, save a reference to it when you create it.
  442.  
  443. See the Engineering Note “Promises” for sample code.
  444.  
  445.  
  446. Resources
  447.  
  448. ODF 1 enables you to define menus, views, and About boxes in resources. By convention cross-platform resource definitions are kept in files with the suffix “.fr”. These files are compiled by ODFRC, ODF’s cross-platform resource compiler.
  449.  
  450. About Box resource
  451. To display the About box in response to a kODCommandAbout command, call the global method FW_About and pass it your part and the id of your About resource. Note that the About item in the Apple menu is automatically set by ODF to contain your part's name. You do not need to set it up in DoAdjustMenus. 
  452.  
  453. See the Engineering Note “About Box” for sample code.
  454.  
  455. Menu resources
  456. Menus can now be defined in resources. You can remove all of your menu setup code in CMyPart::Initialize and replace it with one line:
  457.     GetMenuBar(ev)->InitializeFromResource(ev, kMyMenuBarResourceID);
  458.  
  459. See the Engineering Note “Menu Resources” for samples.
  460.  
  461. Part Info resource
  462. This is a new resource required in ODF 1. It contains some information that was previously defined in static part members and passed to the FW_CPart constructor. The section “Part API” above tells how to convert this data.
  463.  
  464. See the Engineering Note “Part Info Resource” for more information.
  465.  
  466. View resources
  467. Views can now be defined in resources. You can remove all of your view creation code in CMyFrame::CreateSubViews and replace it with one line:
  468.     CreateSubViewsFromResource(ev, kMyViewResourceID);
  469.  
  470. Make sure that view classes created from resources won't be dead-stripped by the linker. Use the macro FW_DO_NOT_DEAD_STRIP for those classes which are not referenced anywhere else in your part's code. Here is an example from the Form sample part:
  471.     FW_DO_NOT_DEAD_STRIP(FW_CGrowBox);
  472.  
  473. See the Engineering Note “Defining Views in Resources” . 
  474.  
  475.  
  476. Views
  477.  
  478. The hierarchy of view classes has changed a lot. The new class FW_CSuperView represents a view that can contain subviews. The class FW_CGadget has been renamed to FW_CControl, and there are many new classes representing controls. There is a simple view layout management system based on six bindings between a view and its parent view. This is described in the Engineering Note “Layout Management”.
  479.  
  480. Old hierarchy:
  481.    FW_CView
  482.       FW_CFrame
  483.          FW_CEmbeddingFrame
  484.       FW_CGadget
  485.          FW_CButton (Notifier)
  486.             FW_CPushButton
  487.             FW_CRadioButton
  488.          FW_CGrowBox
  489.          FW_CRadioCluster (Receiver)
  490.          FW_CScrollBar (Notifier)
  491.  
  492. New hierarchy:
  493.    FW_CView
  494.       FW_CSuperView (new)
  495.          FW_CFrame
  496.             FW_CDialogFrame (new)
  497.                FW_CAboutFrame (new)
  498.             FW_CEmbeddingFrame
  499.       FW_CControl (Notifier)
  500.          FW_CNativeControl (new)
  501.             FW_CButton (4 kinds, including radio and checkbox)
  502.             FW_CPopupMenu (new)
  503.             FW_CScrollBar
  504.       FW_CEditView (new; Notifier)
  505.       FW_CGrowBox
  506.       FW_CListBox (new; Notifier)
  507.       FW_CStaticText (new)
  508.          FW_CGroupBox (new)
  509.  
  510. FW_CRadioCluster is now a subclass of FW_MReceiver only; it’s no longer a View.
  511.  
  512. • FW_CFrame::AdjustSubViews was renamed AdjustSubViewsLayout.  You need to override it only if your part requires a layout scheme that is more complex than the simple “6-binding” one provided by ODF. There is also a new method AdjustToNewLayout that should be overridden if the view cannot be resized using just binding flags. See the samples Form and Draw where the content view requires special processing.
  513.  
  514. • The classes FW_CRadioButton and FW_CPushButton have been merged into a single class,  FW_CButton. FW_CButton has a "kind" field which tells whether it’s a push-button, radio button, or checkbox.
  515.  
  516. For more information on what has changed in views, see”Managing your Part’s Interface” in the ODF Developer’s Guide Update. Also see the various documents in the Views folder of Engineering Notes.
  517.  
  518. © 1993 - 1996 Apple Computer, Inc. All rights reserved.
  519. Apple, the Apple Logo, Macintosh, and OpenDoc are trademarks of Apple Computer, Inc., registered in the United States and other countries.